package jwt

import (
	"log"
	"net/http"
	"time"
	"toy-car/pkg/e"
	"toy-car/pkg/setting"
	"toy-car/pkg/util"

	"strconv"

	"github.com/gin-gonic/gin"
)

func JWT() gin.HandlerFunc {
	return func(c *gin.Context) {
		var code int
		var data interface{}
		var claims *util.Claims
		var err error

		code = e.SUCCESS
		token := c.Request.Header.Get("X-TOY-TOKEN")
		if token == "" {
			// token获取失败
			code = e.INVALID_PARAMS
			log.Print("token获取为空")
		} else {
			// todo 黑名单处理 redis or mysql

			claims, err = util.ParseToken(token)
			if err != nil {
				code = e.ERROR_AUTH_CHECK_TOKEN_FAIL
				log.Println("token解析失败", err)
			} else if time.Now().Unix() > claims.ExpiresAt {
				code = e.ERROR_AUTH_CHECK_TOKEN_TIMEOUT
				log.Println("token过期", err)
			} else {
				if claims.ExpiresAt-time.Now().Unix() < claims.BufferTime {
					code = e.SUCCESS
					log.Println("开始续租", claims.ExpiresAt, time.Now().Unix(), claims.BufferTime, code)
					// 续租token过期时间
					claims.ExpiresAt = time.Now().Unix() + setting.JwtBufferTime
					newToken, _ := util.ReGenerateToken(claims)
					newClaims, _ := util.ParseToken(newToken)
					c.Header("X-NEW-TOKEN", newToken)
					c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt, 10))
				}
			}
		}

		log.Println("code", code)
		if code != e.SUCCESS {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": code,
				"msg":  e.GetMSG(code),
				"data": data,
			})

			c.Abort()
			return
		}
		c.Set("claims", claims)
		log.Println("----->> code done!", code)
		c.Next()
		log.Println("<<<<-------", code)
	}
}
